package com.xiaobingby.admin.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaobingby.admin.sys.dto.UserDetailsDto;
import com.xiaobingby.admin.sys.dto.UserDto;
import com.xiaobingby.admin.sys.entity.*;
import com.xiaobingby.admin.sys.mapper.PermissionMapper;
import com.xiaobingby.admin.sys.mapper.RoleMapper;
import com.xiaobingby.admin.sys.mapper.RolePermissionMapper;
import com.xiaobingby.admin.sys.mapper.UserMapper;
import com.xiaobingby.admin.sys.service.IUserRoleService;
import com.xiaobingby.admin.sys.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * sys_user 用户表 服务实现类
 * </p>
 *
 * @author XiaoBingBy
 * @since 2018-10-29
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private static final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Autowired
    private IUserService iUserService;

    @Autowired
    private IUserRoleService iUserRoleService;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void addUser(UserDto userDto) {
        // 添加用户
        userDto.setPassword(passwordEncoder.encode("admin"));
        boolean save = iUserService.save(userDto);
        // 删除原关联角色
        UpdateWrapper<UserRole> userRoleUpdateWrapper = new UpdateWrapper<>();
        userRoleUpdateWrapper.eq("user_id", userDto.getId());
        boolean remove = iUserRoleService.remove(userRoleUpdateWrapper);
        // 添加用户角色关联
        boolean addUserRoles = addUserRoles(userDto);
    }

    @Override
    public void updateUser(UserDto userDto) {
        // 更新用户
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.eq("id", userDto.getId());
        User user = new User();
        BeanUtils.copyProperties(userDto, user);
        iUserService.update(user, userUpdateWrapper);
        // 删除原关联角色
        UpdateWrapper<UserRole> userRoleUpdateWrapper = new UpdateWrapper<>();
        userRoleUpdateWrapper.eq("user_id", userDto.getId());
        boolean remove = iUserRoleService.remove(userRoleUpdateWrapper);
        // 添加用户角色关联
        boolean addUserRoles = addUserRoles(userDto);
    }

    @Transactional
    @Override
    public boolean deleteUserRole(Long[] ids) {
        // 删除用户
        iUserService.removeByIds(Arrays.asList(ids));
        // 删除角色
        UpdateWrapper<UserRole> userRoleUpdateWrapper = new UpdateWrapper<>();
        userRoleUpdateWrapper.in("user_id", Arrays.asList(ids));
        boolean remove = iUserRoleService.remove(userRoleUpdateWrapper);
        return false;
    }

    @Override
    public UserDto findUserRolesInfo(Integer id) {
        User user = iUserService.getById(id);
        // 查询用户关联角色
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.eq("user_id", id);
        List<UserRole> userRoles = iUserRoleService.list(userRoleQueryWrapper);
        ArrayList<Long> roleIds = new ArrayList<>();
        userRoles.forEach(item -> {
            roleIds.add(item.getRoleId());
        });
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user, userDto);
        userDto.setRoleIds(roleIds);
        return userDto;
    }

    @Override
    public UserDetailsDto loadUserByUsername(String username) {
        // 查询用户
        UserDetailsDto userDetailsDto = new UserDetailsDto();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = iUserService.getOne(queryWrapper);
        BeanUtils.copyProperties(user, userDetailsDto);
        // 查询角色
        List<Role> userRole = findUserRole(userDetailsDto.getId());
        userDetailsDto.setRoles(userRole);
        // 查询权限
        List<Permission> userPermission = findRolePermission(userDetailsDto.getRoles());
        userDetailsDto.setPermissions(userPermission);
        return userDetailsDto;
    }

    /**
     * 查询用户角色
     *
     * @param id
     * @return
     */
    private List<Role> findUserRole(Long id) {
        QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
        userRoleQueryWrapper.eq("user_id", id);
        List<UserRole> userRoles = iUserRoleService.list(userRoleQueryWrapper);
        ArrayList<Long> roleIds = new ArrayList<>();
        userRoles.parallelStream().forEach(item -> {
            roleIds.add(item.getRoleId());
        });
        List<Role> roles = roleMapper.selectBatchIds(roleIds);
        return roles;
    }

    /**
     * 查询用户权限
     *
     * @param id
     * @param roles
     * @return
     */
    private List<Permission> findRolePermission(List<Role> roles) {
        List<Long> roleIds = new ArrayList<>();
        roles.parallelStream().forEach(item -> {
            roleIds.add(item.getId());
        });
        QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
        rolePermissionQueryWrapper.in("role_id", roleIds);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionQueryWrapper);
        ArrayList<Long> permissionIds = new ArrayList<>();
        rolePermissions.parallelStream().forEach(item -> {
            permissionIds.add(item.getPermissionId());
        });
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.in("id", permissionIds);
        permissionQueryWrapper.eq("type", "1");
        List<Permission> permissions = permissionMapper.selectList(permissionQueryWrapper);
        return permissions;
    }

    /**
     * 添加用户角色关联
     *
     * @param userDto
     * @return
     */
    private boolean addUserRoles(UserDto userDto) {
        ArrayList<UserRole> userRoles = new ArrayList<>();
        Collection<Long> roleIds = userDto.getRoleIds();
        roleIds.forEach(item -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(userDto.getId());
            userRole.setRoleId(item);
            userRoles.add(userRole);
        });
        boolean saveBatch = iUserRoleService.saveBatch(userRoles);
        return saveBatch;
    }


}
